package com.kxmall.web.controller.group.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kxmall.common.core.domain.PageQuery;
import com.kxmall.common.core.page.TableDataInfo;
import com.kxmall.common.enums.GroupShopAutomaticRefundType;
import com.kxmall.common.enums.StatusType;
import com.kxmall.common.exception.ServiceException;
import com.kxmall.common.utils.redis.RedisUtils;
import com.kxmall.group.domain.KxGroupShop;
import com.kxmall.group.domain.KxGroupShopProduct;
import com.kxmall.group.domain.bo.KxGroupShopBo;
import com.kxmall.group.domain.vo.KxGroupShopVo;
import com.kxmall.group.mapper.KxGroupShopMapper;
import com.kxmall.group.mapper.KxGroupShopProductMapper;
import com.kxmall.product.domain.KxStoreProduct;
import com.kxmall.product.domain.KxStoreProductAttr;
import com.kxmall.product.mapper.KxStoreProductAttrMapper;
import com.kxmall.product.mapper.KxStoreProductMapper;
import com.kxmall.storage.domain.KxGoodsOutStock;
import com.kxmall.web.controller.group.service.IKxGroupShopService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 团购Service业务层处理
 *
 * @author kxmall
 * @date 2023-10-07
 */
@RequiredArgsConstructor
@Service
public class KxGroupShopServiceImpl implements IKxGroupShopService {

    private final KxGroupShopMapper baseMapper;

    private final KxGroupShopProductMapper groupShopProductMapper;

    private final KxStoreProductMapper productMapper;

    private final KxStoreProductAttrMapper productAttrMapper;

    private static final String GROUP_SHOP_CACHE = "CA_GROUP_SHOP";

    /**
     * 查询团购
     */
    @Override
    public KxGroupShopVo queryById(Long id) {
        KxGroupShopVo groupShopVo = baseMapper.selectVoById(id);
        groupShopVo.setGroupShopSkuList(groupShopProductMapper.selectList(new LambdaQueryWrapper<KxGroupShopProduct>()
                .eq(KxGroupShopProduct::getGroupShopId, id)));
        return groupShopVo;
    }

    /**
     * 查询团购列表
     */
    @Override
    public TableDataInfo<KxGroupShopVo> queryPageList(KxGroupShopBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<KxGroupShop> lqw = buildQueryWrapper(bo);
        Page<KxGroupShopVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询团购列表
     */
    @Override
    public List<KxGroupShopVo> queryList(KxGroupShopBo bo) {
        LambdaQueryWrapper<KxGroupShop> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<KxGroupShop> buildQueryWrapper(KxGroupShopBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<KxGroupShop> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, KxGroupShop::getId, bo.getId());
        lqw.eq(bo.getStatus() != null, KxGroupShop::getStatus, bo.getStatus());
        lqw.eq(bo.getStorageId() != null, KxGroupShop::getStorageId, bo.getStorageId());
        lqw.in(!CollectionUtils.isEmpty(bo.getStorageIds()), KxGroupShop::getStorageId, bo.getStorageIds());
        return lqw;
    }

    /**
     * 新增团购
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(KxGroupShopBo bo) {
        // 1.转化为对应的GroupShopSkuDo类的链表
        List<KxGroupShopProduct> groupShopSkuDOList = bo.getGroupShopSkuList().stream().sorted(Comparator.comparing(KxGroupShopProduct::getProductGroupShopPrice)).collect(Collectors.toList());

        if (bo.getStartTime().compareTo(bo.getEndTime()) >= 0) {
            throw new ServiceException("团购开始时间必须小于结束时间");
        }

        // 2.检验数据库中是否存在spuId对应的sku
        KxStoreProduct product = productMapper.selectById(bo.getProductId());
        List<KxStoreProductAttr> productAttrs = productAttrMapper.selectList((new QueryWrapper<KxStoreProductAttr>().eq("product_id", bo.getProductId())));
        if (product == null || CollectionUtils.isEmpty(productAttrs)) {
            throw new ServiceException("团购商品中对应的spu不存在或只有spu存在,没有对应sku存在");
        }
        // 2.1 检验groupShop表中是否存在此商品
        Long count = baseMapper.selectCount((new QueryWrapper<KxGroupShop>().eq("product_id", bo.getProductId()).eq("storage_id", bo.getStorageId())));
        if (count > 0) {
            throw new ServiceException("该商品已经是团购商品");
        }

        Date timeStart = bo.getStartTime();
        Date timeEnd = bo.getEndTime();
        Date now = new Date();
        KxGroupShop groupShopDO = new KxGroupShop();

        groupShopDO.setAlreadyBuyNumber(0L);
        groupShopDO.setMinimumNumber(bo.getMinimumNumber());
        groupShopDO.setStartTime(bo.getStartTime());
        groupShopDO.setEndTime(bo.getEndTime());
        groupShopDO.setAutomaticRefund(bo.getAutomaticRefund().compareTo(0) > 0 ? GroupShopAutomaticRefundType.YES.getCode() : GroupShopAutomaticRefundType.NO.getCode());
        groupShopDO.setProductId(bo.getProductId());
        groupShopDO.setMinPrice(groupShopSkuDOList.get(0).getProductGroupShopPrice());
        groupShopDO.setMaxPrice(groupShopSkuDOList.get(groupShopSkuDOList.size() - 1).getProductGroupShopPrice());
        groupShopDO.setCreateTime(now);
        groupShopDO.setUpdateTime(now);
        groupShopDO.setStorageId(bo.getStorageId());
        // 3.设置是否在活动时间的状态
        setGroupShopStatus(now, bo.getStartTime().getTime(), bo.getEndTime().getTime(), product, groupShopDO);
        if (baseMapper.insert(groupShopDO) <= 0) {
            throw new ServiceException("团购商品spu添加出误");
        }

//        if (productAttrs.size() != groupShopSkuDOList.size()) {
//            throw new ServiceException("团购商品sku数量不对应");
//        }
        // 4.插入groupShopSkuList
        this.insertGroupShopSkuList(groupShopSkuDOList, productAttrs, groupShopDO.getId(), now);
        RedisUtils.deleteKeys(GROUP_SHOP_CACHE + "*");
        return true;
    }

    private void insertGroupShopSkuList(List<KxGroupShopProduct> groupShopSkuDOList, List<KxStoreProductAttr> skuDOList, Long groupShopId, Date now) throws ServiceException {
        for (KxGroupShopProduct groupShopSkuDO : groupShopSkuDOList) {
            boolean judge = false;
            for (KxStoreProductAttr sku : skuDOList) {
                if (sku.getId().equals(groupShopSkuDO.getProductAttrId())) {
                    judge = true;
                    break;
                }
            }

//            if (!judge) {
//                throw new ServiceException("团购商品sku所对应的sku_id错误");
//            }

            if (groupShopSkuDO.getProductGroupShopPrice() == null || groupShopSkuDO.getProductGroupShopPrice().compareTo(BigDecimal.ZERO) == 0) {
                throw new ServiceException("团购商品sku价格为空,或者为0");
            }

            groupShopSkuDO.setGroupShopId(groupShopId);
            groupShopSkuDO.setUpdateTime(now);
            groupShopSkuDO.setCreateTime(now);
            if (groupShopProductMapper.insert(groupShopSkuDO) <= 0) {
                throw new ServiceException("团购商品sku添加出错");
            }
        }
    }

    private void setGroupShopStatus(Date now, Long gmtStart, Long gmtEnd, KxStoreProduct storeProduct, KxGroupShop groupShopDO) {
        if (now.getTime() >= gmtStart.longValue() && now.getTime() < gmtEnd.longValue()) {
            //3.1 商品本身是否处于下架状态
            if (storeProduct.getIsShow().equals(StatusType.ACTIVE.getCode())) {
                groupShopDO.setStatus(StatusType.ACTIVE.getCode());
            } else {
                groupShopDO.setStatus(StatusType.LOCK.getCode());
            }
        } else {
            groupShopDO.setStatus(StatusType.LOCK.getCode());
        }
    }

    /**
     * 修改团购
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(KxGroupShopBo bo) {
        // 1.转化为对应的GroupShopSkuDo类的链表
        // 1.转化为对应的GroupShopSkuDo类的链表
        List<KxGroupShopProduct> groupShopSkuDOList = bo.getGroupShopSkuList().stream().sorted(Comparator.comparing(KxGroupShopProduct::getProductGroupShopPrice)).collect(Collectors.toList());

        if (bo.getStartTime().compareTo(bo.getEndTime()) >= 0) {
            throw new ServiceException("团购开始时间必须小于结束时间");
        }

        // 2.检验数据库中是否存在spuId对应的sku
        KxStoreProduct product = productMapper.selectById(bo.getProductId());
        List<KxStoreProductAttr> productAttrs = productAttrMapper.selectList((new QueryWrapper<KxStoreProductAttr>().eq("product_id", bo.getProductId())));
        if (product == null || CollectionUtils.isEmpty(productAttrs)) {
            throw new ServiceException("团购商品中对应的spu不存在或只有spu存在,没有对应sku存在");
        }

        KxGroupShop groupShopDO = baseMapper.selectById(bo.getId());
        if (groupShopDO == null) {
            throw new ServiceException("团购信息不存在！");
        }

        if (groupShopDO.getStatus() > 0) {
            throw new ServiceException("团购商品已经在团购中.无法进行编辑或修改操作");
        }


        Date now = new Date();
        groupShopDO.setAlreadyBuyNumber(0L);
        groupShopDO.setMinimumNumber(bo.getMinimumNumber());
        groupShopDO.setStartTime(bo.getStartTime());
        groupShopDO.setEndTime(bo.getEndTime());
        groupShopDO.setAutomaticRefund(bo.getAutomaticRefund().compareTo(0) > 0 ? GroupShopAutomaticRefundType.YES.getCode() : GroupShopAutomaticRefundType.NO.getCode());
        groupShopDO.setProductId(bo.getProductId());
        groupShopDO.setMinPrice(groupShopSkuDOList.get(0).getProductGroupShopPrice());
        groupShopDO.setMaxPrice(groupShopSkuDOList.get(groupShopSkuDOList.size() - 1).getProductGroupShopPrice());
        groupShopDO.setUpdateTime(now);
        groupShopDO.setStorageId(bo.getStorageId());

        setGroupShopStatus(now, bo.getStartTime().getTime(), bo.getEndTime().getTime(), product, groupShopDO);
        if (baseMapper.updateById(groupShopDO) <= 0) {
            throw new ServiceException("团购商品spu添加出误");
        }

        if (groupShopProductMapper.delete((new QueryWrapper<KxGroupShopProduct>().eq("group_shop_id", bo.getId()))) <= 0) {
            throw new ServiceException("团购商品sku删除出错");
        }

//        if (skuDOList.size() != groupShopSkuDOList.size()) {
//            throw new ServiceException(ExceptionDefinition.GROUP_SHOP_SKU_NUMBER_ERROR);
//        }
        // 4.插入groupShopSkuList
        this.insertGroupShopSkuList(groupShopSkuDOList, productAttrs, groupShopDO.getId(), now);
        RedisUtils.deleteKeys(GROUP_SHOP_CACHE + "*");
        return true;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(KxGroupShop entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除团购
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        for (Long id : ids) {
            KxGroupShop groupShopDO = baseMapper.selectById(id);
            if (groupShopDO == null) {
                throw new ServiceException("团购商品中对应的spu不存在或只有spu存在,没有对应sku存在");
            }

            if (groupShopDO.getStatus() > 0) {
                throw new ServiceException("团购商品已经在团购中.无法进行编辑或修改操作");
            }

            if (baseMapper.deleteById(id) <= 0) {
                throw new ServiceException("团购商品spu删除出错");
            }
            if (groupShopProductMapper.delete((new QueryWrapper<KxGroupShopProduct>().eq("group_shop_id", id))) <= 0) {
                throw new ServiceException("团购商品sku删除出错");
            }

            RedisUtils.deleteKeys(GROUP_SHOP_CACHE + "*");
        }
        return true;
    }
}
